package com.mv.spring.web.handler;

import com.mv.spring.bean.BeanFactory;
import com.mv.spring.web.servlet.DispatcherServlet;
import com.mv.webserver.http.HttpRequest;
import com.mv.webserver.http.HttpResponse;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class MappingHandler {
	private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
	
    private String uri;
    private Class<?> controller;
    private Method method;
    private String[] args;

    /**
     * @param uri        如 /getSalary.json
     * @param controller
     * @param method
     * @param args
     */
    MappingHandler(String uri, Class<?> controller, Method method, String[] args) {
        this.uri = uri;
        this.controller = controller;
        this.method = method;
        this.args = args;
    }
    
    public String getUrl() {return uri;}

    //处理 解析
    public boolean handle(ServletRequest req, ServletResponse res) throws
            IllegalAccessException, InvocationTargetException, IOException {
    	
    	Object response;
    	 Object controllerBean = BeanFactory.getBean(this.controller);
    	
        // 先根据方法参数名，提取 request 中的参数值
//        Object[] parameters = new Object[this.args.length];
//        for (int i = 0; i < args.length; i++) {
//            parameters[i] = req.getParameter(this.args[i]);
//        }
//        
//        log.info("parameters args size :" + this.args.length + " parms len" +  parameters.length + " parameters :" + parameters.toString());

        // 获取对应 Controller 类实例以调用方法
        /*
        log.info("controllerBean :" + controllerBean.toString());
        if(parameters.length == 0) {
       	 //response = this.method.invoke(controllerBean);
       	 //response = this.method.invoke(controllerBean, parameters);
       	 response = this.method.invoke(controllerBean, req,res);
       }else {
       	 response = this.method.invoke(controllerBean, parameters);
       }
       */
       
        //if(method.getParameterTypes() .contains("ServletRequest"))
        Class<?>[] classes = method.getParameterTypes();
        log.info("getParameter count:" + method.getParameterCount()); 
        int parms_id = 0, parm_ann_id = 0;
        Object[] parameters = new Object[ method.getParameterCount()];
        for (Class<?> cls: classes) {
        	 if(cls == ServletRequest.class){
        		 log.info("getParameter type ServletRequest");
        		 parameters[parms_id] = req;
        	 }else if(cls == ServletResponse.class){
            	log.info("getParameter type ServletResponse");
            	parameters[parms_id] = res;
            }else {
            	log.info("cls name" + cls.getName() + "parm_ann_id " + parm_ann_id);
            	parameters[parms_id] = req.getParameter(this.args[parm_ann_id]); 
            	parm_ann_id++;
            }
            parms_id++;
        }
        res.setCharacterEncoding("GBK"); //UTF-8
        response = this.method.invoke(controllerBean, parameters);
        //response = this.method.invoke(controllerBean, req,res);
        
       
        // 只支持响应纯字符串
        res.getWriter().println(response.toString());

        return true;
    }
    
    //处理 解析
    public boolean handleInnerTomcat(HttpRequest req, HttpResponse res) throws
            IllegalAccessException, InvocationTargetException, IOException {
        String servletUri =  req.getRequestURI();
        if (!this.uri.equals(servletUri)) {
            return false;
        }
    
        // 获取对应 Controller 类实例以调用方法
        Object controllerBean = BeanFactory.getBean(this.controller);
        Object response = this.method.invoke(controllerBean, req, res);
   
        return true;
    }

	@Override
	public String toString() {
		return "MappingHandler [uri=" + uri + ", controller=" + controller + ", method=" + method + ", args="
				+ Arrays.toString(args) + "]";
	}    
    
}
